////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2008 Michiel Helvensteijn                                    //
//                                                                            //
// This file is part of the Mist compiler.                                    //
//                                                                            //
// The Mist compiler is free software: you can redistribute it and/or modify  //
// it under the terms of the GNU General Public License as published by       //
// the Free Software Foundation, either version 3 of the License, or          //
// (at your option) any later version.                                        //
//                                                                            //
// The Mist compiler is distributed in the hope that it will be useful,       //
// but WITHOUT ANY WARRANTY; without even the implied warranty of             //
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              //
// GNU General Public License for more details.                               //
//                                                                            //
// You should have received a copy of the GNU General Public License          //
// along with the Mist compiler.  If not, see <http://www.gnu.org/licenses/>. //
////////////////////////////////////////////////////////////////////////////////

#include "assert.hpp"

/******************************************************************************
 * Includes                                                                   *
 ******************************************************************************/

#include <string>
using std::string;

#include <cstring>

#include "common.hpp"

/******************************************************************************
 * Function Implementations                                                   *
 ******************************************************************************/

AssertionFailure::AssertionFailure(string expression, string function, string file, long line) : _expression(expression), _function(function), _file(file), _line(line) {
} // intentionally empty

const char* AssertionFailure::what() const throw() {
	unsigned int length = file().length() + digit_count(line()) + expression().length() + 30;
	char* message = new char[length];
	message[0] = '\0';
	
	// TODO: Figure out why std::string could not create the c_str() correctly at a certain length
	strcat(message, file().c_str());
	strcat(message, ":");
	strcat(message, to_string(line()).c_str());
	// strcat(message, ": ");
	// strcat(message, function().c_str());
	strcat(message, ": assertion (");
	strcat(message, expression().c_str());
	strcat(message, ") failed");
	
	return message;
}

const string& AssertionFailure::expression() const {
	return _expression;
}

const string& AssertionFailure::function() const {
	return _function;
}

const string& AssertionFailure::file() const {
	return _file;
}

long AssertionFailure::line() const {
	return _line;
}

namespace boost {
	void assertion_failed(char const * expr, char const * function, char const * file, long line) {
		throw AssertionFailure(expr, function, file, line);
	}
}
